package info.thereisonlywe.core.audio;

import info.thereisonlywe.core.essentials.SystemEssentials;

import java.io.File;
import java.io.InputStream;
import java.util.logging.Level;

import javazoom.jlgui.basicplayer.BasicPlayerException;

public class AudioPlayer {

	// two players are used to play audio files consecutively.
	private final AudioPlayerModel player[] = new AudioPlayerModel[2];

	private byte alternator = 0;

	private double gain = 0.5;

	// private final double pan = 0.0;

	public AudioPlayer()
	{
		player[0] = new AudioPlayerModel();
		player[1] = new AudioPlayerModel();
	}

	public synchronized double getVolume()
	{
		return gain;
	}

	// public synchronized double getPan() {
	// return pan;
	// }
	//
	// public synchronized void setPan(double val) {
	// pan = val;
	// if (player == null)
	// return;
	// try {
	// if (player[0].getFile() != null) {
	// player[0].setPan(pan);
	// }
	// if (player[1].getFile() != null) {
	// player[1].setPan(pan);
	// }
	// } catch (BasicPlayerException e) {
	// LiteSystemEssentials.Logger.log(Level.WARNING, e);
	// }
	// }

	public synchronized void setVolume(double val)
	{
		if (gain == val) return;
		gain = val;
		if (player == null) return;
		try
		{
			if (player[0].getFile() != null)
			{
				player[0].setGain(gain);
			}
			if (player[1].getFile() != null)
			{
				player[1].setGain(gain);
			}
		}
		catch (BasicPlayerException e)
		{
			SystemEssentials.Logger.log(Level.WARNING, e);
		}
	}

	// public synchronized void stop(File f) {
	// int pos = getPosition(f);
	// if (pos < 0) //invalid file specified
	// return;
	// try {
	// player[pos].stop();
	// } catch (BasicPlayerException e)
	// {LiteSystemEssentials.Logger.log(Level.WARNING, e);}
	// }

	private synchronized void stop(int n)
	{
		try
		{
			player[n].stop();
		}
		catch (BasicPlayerException e)
		{
			SystemEssentials.Logger.log(Level.WARNING, e);
		}
	}

	public synchronized void pause(File f)
	{
		int pos = getPosition(f);
		if (pos < 0) // invalid file specified
			return;
		try
		{
			player[pos].pause();
		}
		catch (BasicPlayerException e)
		{
			SystemEssentials.Logger.log(Level.WARNING, e.getMessage());
		}
	}

	public synchronized void resume(File f)
	{
		int pos = getPosition(f);
		if (pos < 0) // invalid file specified
			return;
		try
		{
			player[pos].resume();
		}
		catch (BasicPlayerException e)
		{
			SystemEssentials.Logger.log(Level.WARNING, e.getMessage());
		}
	}

	// public synchronized void seek(long val){
	// try {
	// player.seek(val);
	// } catch (BasicPlayerException e) {
	// SimpleSystemEssentials.Logger.log(Level.WARNING, e.getMessage());
	// }
	// }

	public synchronized boolean isComplete(File f)
	{
		int pos = getPosition(f);
		if (pos < 0) // invalid file specified
			return true;
		if (player == null) return true;
		return player[pos].getStatus() == AudioPlayerModel.STOPPED ? true
				: false;
	}

	public synchronized boolean isComplete()
	{
		if (player == null) return true;
		else
		{
			return player[0].getStatus() == AudioPlayerModel.STOPPED
					&& player[1].getStatus() == AudioPlayerModel.STOPPED ? true
					: false;
		}
	}

	public synchronized boolean isCloseToCompletion(File f)
	{
		int pos = getPosition(f);
		if (player == null || pos < 0
				|| player[pos].getBytesToBeProcessed() == -1)
		{
			return true;
		}
		else
		{
			return player[pos].getEncodedBytes() >= player[pos].getFile()
					.length() - 20000 ? true : false;
		}
	}

	public synchronized void reset()
	{
		stop(0);
		stop(1);
		player[0].reset();
		player[1].reset();
		player[0] = new AudioPlayerModel();
		player[1] = new AudioPlayerModel();
	}

	public synchronized void play(File file)
	{
		try
		{
			if (player == null) return;
			player[alternator].reset();
			player[alternator] = new AudioPlayerModel();
			player[alternator].setLineBufferSize(-1);
			player[alternator].open(file);
			player[alternator].play();
			player[alternator].setGain(gain);
			if (alternator == 0) alternator = 1;
			else alternator = 0;
		}
		catch (BasicPlayerException e)
		{
			SystemEssentials.Logger.log(Level.WARNING, e);
		}
	}

	public synchronized void play(InputStream ss)
	{
		try
		{
			if (player == null) return;
			player[alternator].reset();
			player[alternator] = new AudioPlayerModel();
			player[alternator].setLineBufferSize(-1);
			player[alternator].open(ss);
			player[alternator].play();
			player[alternator].setGain(gain);
			if (alternator == 0) alternator = 1;
			else alternator = 0;
		}
		catch (BasicPlayerException e)
		{
			SystemEssentials.Logger.log(Level.WARNING, e);
		}
	}

	private int getPosition(File f)
	{
		if (f == null) return -1;
		else if (player[0].getFile() != null && player[0].getFile().equals(f)) return 0;
		else if (player[1].getFile() != null && player[1].getFile().equals(f)) return 1;
		else return -1;
	}

	public float getFrameRate(File f)
	{
		int pos = getPosition(f);
		if (pos != -1) return player[pos].m_line.getFormat().getFrameRate();
		else
		{
			return -1;
		}
	}
}
